package network

import (
	"World/pb"
	pmgr "World/playermgr"
	"time"

	"World/common/logger"
	_ "errors"
	"log"
	"net"
	"reflect"

	"github.com/golang/protobuf/proto"
)

type MessageHandler func(conn net.Conn, header pb.MessageHeader, msg interface{})

type MessageInfo struct {
	msgType    reflect.Type
	msgHandler MessageHandler
}

var (
	msg_map = make(map[uint16]MessageInfo)
)

func MsgIDExist(msgid uint16) bool {
	if _, ok := msg_map[msgid]; ok {
		return true
	}
	return false
}

func RegisterMessage(msgid uint16, msg interface{}, handler MessageHandler) {

	var info MessageInfo
	info.msgType = reflect.TypeOf(msg.(proto.Message))
	info.msgHandler = handler

	msg_map[msgid] = info
}

func HandleRawData(conn net.Conn, header pb.MessageHeader, pdata []byte) {
	player, err := pmgr.GetPlayerFromMap(int(header.PlayerID))
	if err == nil && player != nil {
		player.LastAt = time.Now().Unix()
	}
	if info, ok := msg_map[header.MsgID]; ok {
		//var data []byte
		var err error
		//消息解密 暂时屏蔽
		/*if header.MsgID == uint16(pb.MSGID_MsgID_Logon_Request) {
			data, err = gorsa.RSA.PriKeyDECRYPT(pdata)
			if err != nil {
				logger.Error("HandleRawData rsa decrypt err:%v", err)
				return
			}
		} else {
			if header.MsgID == uint16(pb.MSGID_MsgID_JoinClub_Reply) {
				logger.Notic("MSGID_MsgID_JoinClub_Reply, header:%+v, AesKey:%v,AesIv:%v, pdata:%v, pdataRaw:%+v", header, string(conf.EncryptCfg.AesKey), string(conf.EncryptCfg.AesIv), string(pdata), pdata)
			}
			bsData, err := base64.StdEncoding.DecodeString(string(pdata))
			if err != nil {
				logger.Error("HandleRawData aes decrypt base64 err:%v, msgid:%v", err, header.MsgID)
				return
			}
			data, err = goEncrypt.AesCbcDecrypt(bsData, conf.EncryptCfg.AesKey, conf.EncryptCfg.AesIv...)
			if err != nil {
				logger.Error("HandleRawData aes decrypt err:%v, msgid:%v", err, header.MsgID)
				return
			}
		}*/
		//data = data[:header.DataLen]
		msg := reflect.New(info.msgType.Elem()).Interface()
		err = proto.Unmarshal(pdata, msg.(proto.Message))
		if err != nil {
			logger.Error("HandleRawData proto decrypt err:%v, msgid:%v, data:%+v", err, header.MsgID, pdata)
			return
		}
		info.msgHandler(conn, header, msg)
		return
	}
	log.Printf("not regist msgid:%v from player:%v\n", header.MsgID, header.PlayerID)
	//	logger.Notic("not regist msgid:%v from player:%v", header.MsgID, header.PlayerID)
}
